#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
flask 的第一应用 hello world
script name: hello
Created on 2020/2/13 21:16 by PyCharm
@author: fujianjian
"""
import os
from datetime import datetime
from threading import Thread

from flask import Flask, request, render_template, flash, session, redirect, url_for
from flask_bootstrap import Bootstrap
from flask_mail import Mail, Message
from flask_migrate import Migrate
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, Email

app = Flask(__name__)
app.secret_key = 'opsmgr2007R2'
# 初始化bootstrap到项目中
bootstrap = Bootstrap(app)
# 初始化moment模块到项目中
moment = Moment(app)


@app.route('/')
def index():
    # 请求上下文
    req_heads = request.headers
    print(req_heads)
    user_agent = req_heads.get('User-Agent')
    return '<h3>Hello World， You brown ist:{}</h3>'.format(user_agent)


# 动态路由。也叫参数站位符
@app.route('/user/<name>')
def user(name):
    return '<h1>hello {}!!!!</h1>'.format(name)


@app.route('/page/index')
def index_page():
    flash('your request too fast, please slow')
    return render_template('hello/index.html')


@app.route('/page/user/<name>')
def user_page(name):
    return render_template('hello/user.html', name=name, curr_time=datetime.utcnow())


@app.route('/db/index', methods=['get', 'post'])
def db_index():
    form = NameForm()
    if form.validate_on_submit():
        user = User.query.filter_by(name=form.name.data).first()
        if user is None:
            user = User(name=form.name.data)
            db.session.add(user)
            db.session.commit()
            session['known'] = True
        else:
            session['known'] = False
        session['name'] = form.name.data
        form.name.data = ''
        return redirect(url_for('db_index'))
    return render_template('hello/db_main.html', form=form, name=session.get('name', 'stranger'),
                           known=session.get('known', False))


# ==============================================================================
# Flask Form 模块
# ==============================================================================


class NameForm(FlaskForm):
    name = StringField('what is you name', validators=[DataRequired()])
    submit = SubmitField('submit')


class EmailForm(FlaskForm):
    name = StringField('name', validators=[DataRequired()])
    email = StringField('email', validators=[DataRequired(), Email()])
    submit = SubmitField('submit')


# ==============================================================================
# Flask Mail 模块
# ==============================================================================

# 数据库相关；orm框架验证
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'hello.sqlite')
# 是否需要追踪对象变化, 默认设置为false 可以降低内存消耗
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)
# 初始化数据迁移仓库
# 为了开放数据库迁移相关命令，Flask-Migrate添加了flask db命令和几个子命令
migrate = Migrate(app, db)


class User(db.Model):
    __tablename__ = 't_users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, index=True)
    password = db.Column(db.String(127), comment='password')
    email = db.Column(db.String(64), comment='email')

    role_id = db.Column(db.Integer, db.ForeignKey('t_roles.id'))

    def __repr__(self):
        return 'User(id={}, name={})'.format(self.id, self.name)


class Role(db.Model):
    __tablename__ = 't_roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)

    users = db.relationship('User', backref='role')

    def __repr__(self):
        return 'Role(id={}, name={})'.format(self.id, self.name)


# ==============================================================================
# Flask Mail 模块
# ==============================================================================

# 设置相关参数
app.config['MAIL_SERVER'] = 'smtp.sina.cn'
app.config['MAIL_PORT'] = 25
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
# app.config[''] = ''

mail = Mail(app)

app.config['MAIL_SUBJECT_PREFIX'] = '[Wsit]'
app.config['MAIL_SENDER'] = 'WSIT ADMIN<nchufujianjian@sina.cn>'


def send_email(to, subject, template, **kwargs):
    msg = Message(app.config['MAIL_SUBJECT_PREFIX'] + subject, sender=app.config['MAIL_SENDER'], recipients=[to])
    msg.body = render_template(template + '.txt', **kwargs)
    msg.html = render_template(template + '.html', **kwargs)
    Thread(target=send_async_email, args=[app, msg]).start()


def send_async_email(wsite, msg):
    """
    异步发送邮件
    :param wsite:
    :param msg:
    :return:
    """
    # Flask-Mail的send方法需要使用current_app,因此必须要激活应用的上下文
    # 使用 with app.app_context():方式激活上下文
    with wsite.app_context():
        mail.send(msg)


@app.route('/mail/index', methods=['get', 'post'])
def mail_index():
    form = EmailForm()
    if form.validate_on_submit():
        user = User.query.filter_by(name=form.name.data).first()
        if user is None:
            user = User(name=form.name.data, email=form.email.data)
            db.session.add(user)
            db.session.commit()
            session['known'] = True
            send_email(app.config['MAIL_SENDER'], 'thank you for register', 'mail/newuser', user=user)
        else:
            session['known'] = False
        session['name'] = form.name.data
        form.name.data = ''
        form.email.data = ''

        return redirect(url_for('mail_index'))
    return render_template('hello/db_main.html', form=form, known=session.get('known', False),
                           name=session.get('name', ''))


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)
